package com.simafei.flow.core.operator;

import cn.hutool.core.text.CharPool;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.NumberUtil;
import com.simafei.flow.core.common.CalcType;
import com.simafei.flow.core.common.Criterion;
import com.simafei.flow.core.common.ExpressionExecutor;
import com.simafei.flow.core.common.Operator;

import java.util.List;
import java.util.Map;

/**
 * @author fengpengju
 */
public interface OperatorHandler {

    /**
     * 处理
     *
     * @param condition 条件项
     * @return 处理结果
     */
    default String handle(Criterion condition) {
        String right = condition.getRight();
        if (condition.getRightType() == CalcType.CONSTANT) {
            // 如果是变量直接交给引擎处理
            if (!NumberUtil.isNumber(right)) {
                // 常量字符串需要加单引号，不然会被当做一个变量来处理从而报错
                right = CharPool.SINGLE_QUOTE + right + CharPool.SINGLE_QUOTE;
            }
        }
        return condition.getLeft() + StrPool.C_SPACE + condition.getOperator().getOperator() + StrPool.C_SPACE + right;
    }

    /**
     * sql left
     *
     * @param condition 条件项
     * @return sql left
     */
    default String sqlLeft(Criterion condition) {
        return condition.getLeft() + StrPool.C_SPACE + condition.getOperator().getSqlOperator() + " ?";
    }

    /**
     * sql right
     *
     * @param condition   条件项
     * @param params 参数
     * @return sql right
     */
    default List<String> sqlRight(Criterion condition, Map<String, Object> params) {
        if (condition.getRightType() == CalcType.CONSTANT) {
            return List.of(condition.getRight());
        } else {
            Object execute = ExpressionExecutor.execute(condition.getRight(), params);
            return List.of((String) execute);
        }
    }

    /**
     * 检查
     *
     * @param condition 条件项
     */
    default void check(Criterion condition) {
    }

    /**
     * 获取操作符
     *
     * @param operator 操作符
     * @return 操作符
     */
    boolean support(Operator operator);
}
